package com.qfedu.edu.iotserver.pay.utils;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by jackiechan on 2018/2/2/上午10:29
 */
public class PayCommonUtil {
    /**
     * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
     *
     * @return boolean
     */
    public static boolean isTenpaySign(String characterEncoding, SortedMap<Object,
                Object> packageParams, String API_KEY) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + API_KEY);
//算出摘要
        String mysign = MD5Util.MD5Encode(sb.toString(),
                characterEncoding).toLowerCase();
        String tenpaySign = ((String) packageParams.get("sign")).toLowerCase();
//System.out.println(tenpaySign + " " + mysign);
        return tenpaySign.equals(mysign);
    }

    /**
     * @param characterEncoding 编码格式
     *                          请求参数
     * @return
     * @author
     * @date 2016-4-22
     * @Description：sign签名
     */
    public static String createSign(String characterEncoding, SortedMap<Object,
            Object> packageParams, String API_KEY) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) &&
                    !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + API_KEY);
        String sign = MD5Util.MD5Encode(sb.toString(),
                characterEncoding).toUpperCase();
        return sign;
    }

    /**
     * @param parameters 请求参数
     * @return
     * @author
     * @date 2016-4-22
     * @Description：将请求参数转换为xml格式的string
     */
    public static String getRequestXml(SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) ||
                    "sign".equalsIgnoreCase(k)) {
                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
            } else {
                sb.append("<" + k + ">" + v + "</" + k + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

    /**
     * 取出⼀个指定⻓度⼤⼩的随机正整数. *
     *
     * @param length int 设定所取出随机数的⻓度。length⼩于11
     * @return int 返回⽣成的随机数。
     */
    public static int buildRandom(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }

    /**
     * 获取当前时间 yyyyMMddHHmmss
     *
     * @return String
     */
    public static String getCurrTime() {
        Date now = new Date();
        SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String s = outFormat.format(now);
        return s;
    }

    /**
     * 统⼀下单,获取⼆维码字符串
     *
     * @param order_price  价格
     * @param body         商品描述
     * @param out_trade_no 订单号
     * @return
     * @throws Exception
     */
    public static String weixin_pay(String order_price, String body, String
            out_trade_no) throws Exception {

        String appid = PayConfigUtil.APP_ID; // appid  在微信上申请的账号上的
        String mch_id = PayConfigUtil.MCH_ID; // 商业号   在微信上申请的账号上的
        String key = PayConfigUtil.API_KEY; // key       在微信上申请的账号上的

        String currTime = PayCommonUtil.getCurrTime();    //获取当前的时间

        //这个截取的是时间的时分秒
        //这里取的时间是时分秒
        String strTime = currTime.substring(8, currTime.length());
        String strRandom = PayCommonUtil.buildRandom(4) + "";
        String nonce_str = strTime + strRandom;

        /* String order_price = "1"; // 价格 注意：价格的单位是分
        String body = "goodssssss"; // 商品名称
        String out_trade_no = "11111338"; // 订单号*/
       // 获取发起电脑 ip  这个就是你系统安装在那个公网的 就要写那个公网的ip地址
        String spbill_create_ip = PayConfigUtil.CREATE_IP;
      // 回调接⼝(这个是腾讯的服务器 在完成支付之后 告诉我们的服务器 支付是成功的 还是失败的)

        String notify_url = PayConfigUtil.NOTIFY_URL;
        //支付方式
        String trade_type = "NATIVE";

        //这里使用到了SortedMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", body);
        packageParams.put("out_trade_no", out_trade_no);
        packageParams.put("total_fee", order_price);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);
        //下面这个是为了防止数据在传输的过程中 被篡改
        // 签名实际上就是 按照上面传输的参数  以某一种算法 生成一个唯一的标识
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
        packageParams.put("sign", sign);
        //下面这句话的意思是将上面的信息转换成  支付 需要的请求格式
        //将上面所有的参数整成XML格式
        //相当于是腾讯服务器 给我们提供了一个 接口  这个接口需要的参数
        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        System.out.println("微信服务器需要的参数:"+requestXML);
        

        //向腾讯的服务器发动请求了
        //下面的这个resXml实际上就是腾讯服务器 给我们返回的信息
        String resXml = HttpUtil.postData(PayConfigUtil.UFDOOER_URL, requestXML);
        System.out.println("微信服务器返回的数据是:"+resXml);
        //这个是将支付服务器返回的内容 转换成map结构
        // 将微信服务器 返回的数据 转换成map结构 方便数据的获取
        Map map = XMLUtil.doXMLParse(resXml);
        //String return_code = (String) map.get("return_code");
        //String prepay_id = (String) map.get("prepay_id");
        // code_url ：这个就是二维码的信息
        //这个信息 就是咋们的二维码信息(实际上就是一个字符串)
        String urlCode = (String) map.get("code_url");
        return urlCode;
    }
}